# ps_scheduling
import numpy as np
from numpy import random
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as axisartist


class PS(object):
    def __init__(self, Fin, Exe, Height, Havedone=0):
        self.constant_Fin = Fin
        self.Fin = Fin
        self.Exe = Exe
        self.Havedone = Havedone
        self.Height = Height


s = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']


def line(x_left, x_right, h):
    dec = 0.1
    x = np.arange(x_left, x_right, dec)
    n = len(x)
    y = h * np.ones(n, dtype=int)
    plt.plot(x_right, h, "g*")
    plt.text(x_right, h + 0.005, s[h - 1] + ":" + str(x_right), ha="center", va="bottom", fontsize=10)
    plt.plot(x, y, c='b')


if __name__ == "__main__":

    total_T = 200  #########横坐标总时间在这调
    # 画图初始化
    fig = plt.figure(figsize=(8, 8))
    ax = axisartist.Subplot(fig, 111)
    fig.add_axes(ax)
    ax.axis[:].set_visible(False)
    ax.axis["x"] = ax.new_floating_axis(0, 0)
    ax.axis["x"].set_axisline_style("->", size=5.0)
    ax.axis["x"].set_axis_direction("top")
    plt.plot(0, 0)
    plt.xlim(0, total_T)

    Fin_pri_q = []
    Fin = [30, 75, 67, 120]  ###########在这里设置结束时间列表
    plt.yticks(np.arange(1, len(Fin) + 1.5, 1))
    Execute_T = [15, 38, 57, 89]  ##############在这里设置执行时间列表
    for i in range(len(Execute_T)):
        tmp_ps = PS(Fin[i], Execute_T[i], i + 1, 0)
        Fin_pri_q.append(tmp_ps)
    cur_T = random.exponential(scale=2)  ####### 在这里设置起始时间
    cor_ps = min(Fin_pri_q, key=lambda x: x.Fin)
    Min_Fin_T = cor_ps.Fin

    while cur_T <= total_T:
        tmp_ps = min(Fin_pri_q, key=lambda x: x.Fin)
        Remain = tmp_ps.Exe - tmp_ps.Havedone
        if cur_T + Remain < Min_Fin_T:
            line(cur_T, cur_T + Remain, tmp_ps.Height)
            cur_T += Remain
            tmp_ps.Havedone = 0
            Fin_pri_q.remove(tmp_ps)
        else:
            line(cur_T, Min_Fin_T, tmp_ps.Height)
            tmp_ps.Havedone += Min_Fin_T - cur_T
            if tmp_ps.Havedone == tmp_ps.Exe:
                tmp_ps.Havedone = 0
                Fin_pri_q.remove(tmp_ps)
            cur_T = Min_Fin_T
            cor_ps.Fin += cor_ps.constant_Fin
            Fin_pri_q.append(cor_ps)
            cor_ps = min(Fin_pri_q, key=lambda x: x.Fin)
            Min_Fin_T = cor_ps.Fin

    plt.show()

